home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
games2
/
rotise12.zip
/
STRING.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-03
|
8KB
|
369 lines
/* string.c -- String operations
December 1989 Mark E. Mallett
Updated:
February 26, 1991 Jonathan Arnold
This file contains routines dealing with character strings.
These include:
tkline Tokenize a line
gettoken Extract a token from a string
strsicmp stricmp that returns sign only.
*/
#include <stdio.h>
#include <string.h>
#ifdef __TURBOC__
#include <alloc.h>
#else
#include <malloc.h>
#endif
#include "rotise.h"
/* External data referenced */
/* NONE */
/* External routines used */
/* NONE */
/* Local data publicly available */
/* NONE */
/* Local routine prototypes */
int tkline PROTO( (char *, char *, char **, int, char *, char *) );
char *gettoken PROTO( (char *, char *, int, char *, char *) );
/* Private data */
/* NONE */
/* tkline( bufP, tbufP, tokcP, tokv, tokmax, vsepP, isepP )
Tokenize a line of text
Accepts :
bufP The buffer containing data to be tokenized
tbufP A buffer in which tokens will be placed
tokv Ptr to tokv array -- ptrs to tokens
tokmax Maximum number of tokens to return
vsepP, isepP Separators, as in call to gettoken() (refer there)
Returns :
<value> Number of tokens extracted
*tokv Ptrs to tokens
Notes :
Caller must ensure that the token buffer is large enough to receive
all of the tokens.
The source and destination buffers may overlap, as long as the
source buffer's address is greater than the token buffer's. Thus,
&bufP[0] can be &tbufP[1] (this is a convenient arrangement).
*/
int tkline ARGLIST( ( bufP, tbufP, tokv, tokmax, vsepP, isepP ) )
NFARG ( char *bufP ) /* Buffer ptr */
NFARG ( AREG1 char *tbufP) /* Token buffer pointer */
NFARG ( AREG2 char **tokv) /* Arg vectors */
NFARG ( int tokmax) /* Max # tokens */
NFARG ( char *vsepP) /* Visible separators */
FARG ( char *isepP) /* Invisible separators */
{
DREG1 int tokC; /* # of tokens */
/* Extract the tokens */
for( tokC = 0;
( tokC < tokmax ) &&
( bufP = gettoken( bufP, tbufP, 9999, vsepP, isepP ) ) != NULL;
++tokC )
{
*tokv++ = tbufP;
while( *tbufP++ != NUL )
;
}
return( tokC );
}
/* gettoken( strP, tokP, tokmax, vsepP, isepP )
Extract a token from a string
Accepts :
strP Source string
tokP Buffer to contain the token
tokmax Maximum lenght of token (including NUL)
vsepP "visible" separators -- chars that will terminate
and will also be returned as single-character tokens;
isepP "invisible" separators -- chars that will terminate
a token and will be deleted from the source string.
Returns :
<value> Ptr to the rest of the string, or NULL if no
more tokens;
*tokP Token extracted
*/
char *gettoken ARGLIST( (strP, tokP, tokmax, vsepP, isepP ) )
NFARG (AREG1 char *strP) /* Source string */
NFARG (AREG2 char *tokP) /* Where to put token */
NFARG (int tokmax) /* Max length of token */
NFARG (char *vsepP) /* Visible separators */
FARG (char *isepP) /* Invisible separators */
{
DREG1 char ch; /* Character */
DREG3 char quote; /* Quoting character */
DREG2 int tokX; /* Index into token string */
AREG3 char *sepP; /* Ptr to separator */
static char sepmsk[128]; /* Separator mask array */
#define SEP_VIS 1
#define SEP_INVIS 2
/* Trap NULL source string pointer */
if ( strP == NULL )
return( NULL );
/* Preprocess separator arrays */
for( sepP = vsepP; ( ch = *sepP++ ) != NUL; )
sepmsk[ch] = SEP_VIS;
for( sepP = isepP; ( ch = *sepP++ ) != NUL; )
sepmsk[ch] |= SEP_INVIS;
/* Strip leading "invisible" separators */
for( ; ( ( ch = *strP ) != NUL ) &&
( ( sepmsk[ch] & SEP_INVIS ) != 0 ); )
++strP;
/* Check for quoted character string */
if ( ( ch == '"' ) || ( ch == '\'' ) ) {
quote = ch;
++strP;
}
else
quote = NUL;
/* Loop to get token characters */
for( tokX = 0; ( ch = *strP ) != NUL; ++strP ) {
/* Check for escaped character */
if ( ( ch == '\\' ) && ( strP[1] != NUL ) )
ch = *++strP; /* Use the escaped char */
/* Check for terminating quote */
else if ( ( quote != NUL ) && ( ch == quote ) ) {
quote = NUL;
++strP;
break;
}
/* Check for delimiter */
else if ( sepmsk[ ch ] != 0 ) {
/* If it's invisible, just skip it */
if ( ( sepmsk[ch] & SEP_INVIS ) != 0 )
++strP;
else {
/* If visible, take it if it's the only char. */
if ( tokX++ == 0 ) {
*tokP++ = ch;
++strP;
}
}
break;
}
/* Add the character to the token */
if ( tokX++ < tokmax -1 )
*tokP++ = ch;
}
*tokP = NUL;
/* Check for end of string */
if ( ( tokX == 0 ) && ( ch == NUL ) )
strP = NULL;
/* Undo the separator array marks */
/* On some systems, this might be faster. */
/* memset( &sepmsk[0], 0, 128 ); */
for( sepP = vsepP; ( ch = *sepP++ ) != NUL; )
sepmsk[ch] = 0;
for( sepP = isepP; ( ch = *sepP++ ) != NUL; )
sepmsk[ch] = 0;
return( strP );
}
/*
*//* strscmp( str1P, str2P )
Like strcmp() but return just the sign.
Accepts :
str1P First string
str2P Second string
Returns :
<value> -1 if str1P < str2P (stringwise, of course)
0 if str1P == str2P
1 if str1P > str2P
Notes :
This mimics the "old" behaviour of strcmp().
*/
int
strscmp( str1P, str2P )
char *str1P; /* First string */
char *str2P; /* Second string */
{
int cmpval; /* Comparison value */
if ( ( cmpval = strcmp( str1P, str2P ) ) < 0 )
return( -1 );
else if ( cmpval == 0 )
return( 0 );
else
return( 1 );
}
/*
*//* stricmp() and strnicmp()
Like strcmp() and strncmp() but ignoring case. These may
not be present in the C library in use, in which case these
routines may be conditionally compiled.
*/
#ifndef HAVE_STRICMP
#include <ctype.h>
int
stricmp( s1, s2 )
register char *s1, *s2;
{
register unsigned char c1, c2;
for( ; ; ) {
c1 = *s1++;
c2 = *s2++;
if ( isupper( c1 ) )
c1 = tolower( c1 );
if ( isupper( c2 ) )
c2 = tolower( c2 );
if ( c1 < c2 )
return( -1 );
if ( c1 > c2 )
return( 1 );
if ( c1 == NUL )
return( 0 );
}
}
int
strnicmp( s1, s2, max )
register char *s1, *s2;
int max;
{
register unsigned char c1, c2;
for( ; max > 0; --max ) {
c1 = *s1++;
c2 = *s2++;
if ( isupper( c1 ) )
c1 = tolower( c1 );
if ( isupper( c2 ) )
c2 = tolower( c2 );
if ( c1 < c2 )
return( -1 );
if ( c1 > c2 )
return( 1 );
if ( c1 == NUL )
return( 0 );
}
return( 0 );
}
/* Chances are if you don't have stricmp, you don't have strupr */
char *
strupr( strP )
char *strP;
{
int ch;
char *workP;
for ( workP = strP; ( ch = *workP ) != NUL; ++workP )
if ( islower( ch ) )
*workP = toupper( ch );
return ( strP );
}
#endif /* HAVE_STRICMP */
#if ultrix
int
memcmp( s1, s2, len )
UBYTE *s1, *s2;
int len;
{
int cmp;
while( len-- > 0 )
if ( ( cmp = ( *s1++ - *s2++ ) ) != 0 )
return( cmp );
return( 0 );
}
#endif
/* strsicmp( str1P, str2P )
Like stricmp() but return just the sign.
Accepts :
str1P First string
str2P Second string
Returns :
<value> -1 if str1P < str2P (stringwise, of course)
0 if str1P == str2P
1 if str1P > str2P
Notes :
*/
int strsicmp ARGLIST( (str1P, str2P) )
NFARG( AREG1 char *str1P ) /* First string */
FARG( AREG2 char *str2P ) /* Second string */
{
DREG1 int cmpval; /* Comparison value */
if ( ( cmpval = stricmp( str1P, str2P ) ) < 0 )
return( -1 );
else if ( cmpval == 0 )
return( 0 );
else
return( 1 );
}